package day17;

import lombok.Getter;

// 泛型
// JDK1.5开始, 一种安全机制
public class Demo01 {
	public static void main(String[] args) {
		Teacher t = new Teacher();
		Student s = new Student();
		//		Tool teacherTool = new Tool() {
		//			@Override
		//			public void doSome(Object obj) {
		//				Teacher t = (Teacher) obj;
		//			}
		//		};
		//		teacherTool.doSome(t);
		//		teacherTool.doSome(s);
		// 以Object为参数类型, 无法限制实参类型
		// 在运行时可能会发生类型转换异常, 这种问题只有运行时才会暴露, 编译时检查不出来

		// 定义接口(或类)时, 使用了泛型表示一个不明确的类型
		// 在创建具体对象时, 需要对泛型的类型进行明确
		Tool<Teacher, String> teacherTool = new Tool<Teacher, String>() {
			@Override
			public void doSome(Teacher obj) {
				// .....
			}

			@Override
			public String doOther(Teacher obj) {
				return "aaa";
			}
		};

		teacherTool.doSome(t);
		// teacherTool.doSome(s);
		// 使用泛型的好处: 将运行时才会暴露的问题, 提前到编译期, 可以有效避免问题的发生, 提高程序的健壮性

		Tool<Student, Double> studentTool = new Tool<Student, Double>() {

			@Override
			public void doSome(Student obj) {
				// TODO Auto-generated method stub

			}

			@Override
			public Double doOther(Student obj) {
				// TODO Auto-generated method stub
				return null;
			}
		};
		studentTool.doOther(s);
		// studentTool.doSome(t);

	}
}

// -----------------------------------------------

// 在定义接口(或类)时, 如果要操作的目标类型不明确时, 可以用泛型表示
// 当创建具体对象时, 明确泛型的具体类型
interface Tool<T, R> {
	public void doSome(T obj);

	public R doOther(T obj);
}

@Getter
class Teacher {
	private String name = "ZhangSan";
	private String course = "java";
}

@Getter
class Student {
	private String name = "LaoWang";
	private Double score = 90D;
}